package cn.zhaoyuening.zhaocloud.provider.listener.impl;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import cn.zhaoyuening.zhaocloud.common.bean.CloudServiceBean;
import cn.zhaoyuening.zhaocloud.provider.handler.CloudServiceHandler;
import cn.zhaoyuening.zhaocloud.provider.listener.CloudServiceCallListener;

/**
 * 与Spring IOC容器相关的服务调用监控
 * 
 * @author 赵岳宁
 *
 */
public class BaseCloudServiceCallListener implements CloudServiceCallListener {
	// 线程池
	private ExecutorService executorService = Executors.newWorkStealingPool();
	// 需要监听的端口
	private Integer port;
	private ServerSocket serverSocket;
	private Set<CloudServiceBean> serviceSet;
	private CloudServiceHandler serviceHandler;

	public BaseCloudServiceCallListener(Integer port, 
			CloudServiceHandler serviceHandler) {
		this.port = port;
		this.serviceSet = serviceSet;
		this.serviceHandler = serviceHandler;
		// 开启serverSocket
		try {
			this.serverSocket = new ServerSocket(port);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void startListener(TreeSet<CloudServiceBean> serviceSet) {
		this.serviceSet = serviceSet;
		//监听端口
		executorService.execute(new Runnable() {
			
			public void run() {
				while(true){
					try {
						executorService.execute(new SocketRunnable(serverSocket.accept()));
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		});
	}

	class SocketRunnable implements Runnable {
		private Socket socket = null;
		
		public SocketRunnable(Socket socket){
			this.socket = socket;
		}
		
		public void run() {
			ObjectInputStream ois = null;
			ObjectOutputStream oos = null;
			try {
				ois = new ObjectInputStream(socket.getInputStream());
				oos = new ObjectOutputStream(socket.getOutputStream());

				// 获取远程调用信息
				String className = ois.readUTF();
				String version = ois.readUTF();
				// 查看是否为暴露的服务
				boolean isContains = serviceSet.contains(new CloudServiceBean(className, version));
				if (!isContains) {
					// 申请服务不在暴露范围内,非法请求
					return;
				}
				String methodName = ois.readUTF();
				Class<?>[] parameterTypes = (Class<?>[]) ois.readObject();
				Object[] args = (Object[]) ois.readObject();
				
				//调用指定服务的指定方法获取结果
				Object result = serviceHandler.serviceCall(className, methodName, parameterTypes, args);
				oos.writeObject(result);
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				try {
					if (ois != null)
						ois.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
				try {
					if (oos != null)
						oos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
				try {
					if (socket != null)
						socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

		}

	}

}
